package com.ssy.lingxi.order.serviceimpl.web;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.constant.basic.UserLoginSourceEnum;
import com.ssy.lingxi.common.constant.order.*;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberInnerControllerFeign;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignQueryVO;
import com.ssy.lingxi.order.entity.OrderDO;
import com.ssy.lingxi.order.entity.OrderProcessTaskDO;
import com.ssy.lingxi.order.entity.OrderProductDO;
import com.ssy.lingxi.order.model.bo.*;
import com.ssy.lingxi.order.model.constant.*;
import com.ssy.lingxi.order.model.dto.*;
import com.ssy.lingxi.order.model.vo.basic.request.*;
import com.ssy.lingxi.order.model.vo.basic.response.*;
import com.ssy.lingxi.order.model.vo.buyer.request.*;
import com.ssy.lingxi.order.model.vo.buyer.response.BuyerPayResultDetailVO;
import com.ssy.lingxi.order.model.vo.mobile.request.BuyerOrderVO;
import com.ssy.lingxi.order.model.vo.mobile.request.MobileBusinessOrderVO;
import com.ssy.lingxi.order.model.vo.mobile.response.MobileProcessDetailVO;
import com.ssy.lingxi.order.model.vo.vendor.request.AgentOrderVO;
import com.ssy.lingxi.order.model.vo.vendor.request.AgentPurchaseOrderVO;
import com.ssy.lingxi.order.model.vo.vendor.request.VendorTransferOrderVO;
import com.ssy.lingxi.order.repository.OrderRepository;
import com.ssy.lingxi.order.service.base.*;
import com.ssy.lingxi.order.service.web.*;
import com.ssy.lingxi.order.utils.NumberUtil;
import com.ssy.lingxi.order.utils.OrderStringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 订单创建相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-17
 */
@Service
public class OrderCreationServiceImpl implements IOrderCreationService {

    private final static Logger logger = LoggerFactory.getLogger(OrderCreationServiceImpl.class);

    @Resource
    private IBaseCacheService baseCacheService;

    @Resource
    private IBaseOrderProcessService baseOrderProcessService;

    @Resource
    private IBaseOrderService baseOrderService;

    @Resource
    private IBaseOrderAuthService baseOrderAuthService;

    @Resource
    private IBaseOrderTaskService baseOrderTaskService;

    @Resource
    private IBaseOrderProductService baseOrderProductService;

    @Resource
    private IBaseOrderPaymentService baseOrderPaymentService;

    @Resource
    private IBaseOrderContractService baseOrderContractService;

    @Resource
    private IBaseOrderInvoiceService baseOrderInvoiceService;

    @Resource
    private IBaseOrderConsigneeService baseOrderConsigneeService;

    @Resource
    private IBaseOrderPromotionService baseOrderPromotionService;

    @Resource
    private IBaseOrderCouponService baseOrderCouponService;

    @Resource
    private IBaseOrderRequirementService baseOrderRequirementService;

    @Resource
    private IBaseOrderHistoryService baseOrderHistoryService;

    @Resource
    private IBuyerOrderService buyerOrderService;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private IOrderTimeParamService orderTimeParamService;

    @Resource
    private IBaseOrderScheduleService baseOrderScheduleService;

    @Resource
    private IOrderParamConfigService orderParamConfigService;

    @Resource
    private IBaseOrderDeductionService baseOrderDeductionService;

    @Resource
    private MemberInnerControllerFeign memberInnerControllerFeign;

    /**
     * APP-根据供应商会员信息和商城id获取预约时长和配置配送时间段
     * @param headers HttpHeaders信息
     * @param deliveryDateVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderDeliveryDateVO> findMobileDeliveryDate(HttpHeaders headers, MobileDeliveryDateVO deliveryDateVO){
        baseCacheService.checkUserFromCache(headers);
        return orderTimeParamService.findBuyerDeliveryDate(deliveryDateVO.getVendorMemberId(), deliveryDateVO.getVendorRoleId(), deliveryDateVO.getShopId());
    }

    /**
     * “进货单” - 判断是否可以合并下单
     *
     * @param headers    HttpHeaders信息
     * @param separateVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<Void> checkOrderMergeCondition(HttpHeaders headers, OrderSeparateVO separateVO) {
        baseCacheService.checkUserFromCache(headers);
        return baseOrderProcessService.checkOrderMergeCondition(separateVO);
    }

    /**
     * 订单创建之前，查询支付方式和支付渠道信息
     *
     * @param headers HttpHeader信息
     * @param separateVO   接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderProcessDetailVO> findOrderProcessPaymentSetting(HttpHeaders headers, OrderSeparateVO separateVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return findOrderProcessPaymentSetting(loginUser.getMemberId(), loginUser.getMemberRoleId(), separateVO);
    }

    /**
     * 订单创建之前，查询支付方式和支付渠道信息
     * @param buyerMemberId 采购会员Id
     * @param buyerRoleId   采购会员角色Id
     * @param separateVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderProcessDetailVO> findOrderProcessPaymentSetting(Long buyerMemberId, Long buyerRoleId, OrderSeparateVO separateVO) {
        OrderProcessDetailVO queryVO = new OrderProcessDetailVO();

        //Step 1: 查询供应商交易流程规则
        List<VendorProductBO> vendorProducts = separateVO.getVendors().stream().map(vendor -> {
            VendorProductBO vendorProduct = new VendorProductBO();
            vendorProduct.setVendorMemberId(vendor.getVendorMemberId());
            vendorProduct.setVendorRoleId(vendor.getVendorRoleId());
            vendorProduct.setProducts(vendor.getProducts().stream().map(product -> new OrderProductBO(product.getProductId(), product.getSkuId())).collect(Collectors.toList()));
            return vendorProduct;
        }).collect(Collectors.toList());

        List<OrderSeparateProductVO> productList = separateVO.getVendors().stream().flatMap(v -> v.getProducts().stream()).collect(Collectors.toList());

        OrderTradeProcessTypeEnum tradeProcessTypeEnum = OrderTradeProcessTypeEnum.ORDER_TRADE;
        if (CollUtil.isNotEmpty(productList) && productList.get(0).getCrossBorder() != null && productList.get(0).getCrossBorder()) {
            tradeProcessTypeEnum = OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT;
        }

        Wrapper<OrderTradeProcessBO> tradeProcessResult = baseOrderProcessService.findVendorTradeProcess(separateVO.getShopId(), tradeProcessTypeEnum, vendorProducts);
        if(tradeProcessResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(tradeProcessResult.getCode(), tradeProcessResult.getMessage());
        }

        queryVO.setRequired(tradeProcessResult.getData().getPayTimes().compareTo(0) > 0);
        queryVO.setHasContract(tradeProcessResult.getData().getHasContract());
        queryVO.setContractId(tradeProcessResult.getData().getContractId());
        queryVO.setPayNodes(CollectionUtils.isEmpty(tradeProcessResult.getData().getPayNodes()) ? new ArrayList<>() : tradeProcessResult.getData().getPayNodes().stream().filter(payNode -> payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).map(payNode -> new OrderPayNodeDetailVO(payNode.getBatchNo(), payNode.getPayNode(), payNode.getPayRate())).sorted(Comparator.comparingInt(OrderPayNodeDetailVO::getBatchNo)).collect(Collectors.toList()));
        queryVO.setFirstPayRate(queryVO.getRequired() ? tradeProcessResult.getData().getPayNodes().stream().filter(payNode -> payNode.getSerialNo().equals(1) && payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).min(Comparator.comparingInt(PayNodeBO::getBatchNo)).map(PayNodeBO::getPayRate).orElse(BigDecimal.ZERO) : BigDecimal.ZERO);

        if(queryVO.getRequired()) {
            List<VendorBO> vendors = separateVO.getVendors().stream().map(v -> new VendorBO(v.getVendorMemberId(), v.getVendorRoleId())).collect(Collectors.toList());
            //如果需要支付，查询平台后台的会员支付策略设置
            Wrapper<List<OrderPayTypeDetailVO>> payTypesResult = baseOrderProcessService.findMemberPayment(buyerMemberId, buyerRoleId, vendors);
            if(payTypesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(payTypesResult.getCode(), payTypesResult.getMessage());
            }

            queryVO.setPayTypes(payTypesResult.getData());
        } else {
            queryVO.setPayTypes(new ArrayList<>());
        }

        return Wrapper.success(queryVO);
    }

    /**
     * 进货单下单 - 创建采购订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createBuyerOrder(HttpHeaders headers, BuyerOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return createBuyerOrder(loginUser, orderVO);
    }

    /**
     * 代客下单 - 进货单下单
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public Wrapper<OrderCompleteVO> createAgentPurchaseOrder(HttpHeaders headers, AgentPurchaseOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        //Step 1: 规则校验
        //b. 跨境商品不能与其他商品一起下单
        List<Boolean> crossBorders = orderVO.getProducts().stream().map(MobileOrderProductVO::getCrossBorder).distinct().collect(Collectors.toList());
        if (crossBorders.size() > 1) {
            return Wrapper.fail(ResponseCode.ORDER_PRODUCT_TRADE_PROCESS_IS_DIFFERENT);
        }

        //b.校验供应商的交易流程规则配置
        Map<VendorBO, List<MobileOrderProductVO>> vendorProductMap = orderVO.getProducts().stream().collect(Collectors.groupingBy(product -> new VendorBO(product.getVendorMemberId(), product.getVendorRoleId())));
        List<VendorProductBO> vendorProducts = vendorProductMap.entrySet().stream().map(entry -> {
            VendorProductBO vendorProduct = new VendorProductBO();
            vendorProduct.setVendorMemberId(entry.getKey().getVendorMemberId());
            vendorProduct.setVendorRoleId(entry.getKey().getVendorRoleId());
            vendorProduct.setProducts(entry.getValue().stream().map(p -> new OrderProductBO(p.getProductId(), p.getSkuId())).collect(Collectors.toList()));
            return vendorProduct;
        }).collect(Collectors.toList());

        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getShopId(), crossBorders.get(0) ? OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT : OrderTradeProcessTypeEnum.ORDER_TRADE, vendorProducts);
        if (processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //交易流程是否需要支付、第一次支付的比例
        boolean processPayment = processResult.getData().getPayTimes().compareTo(0) > 0;
        BigDecimal firstPayRate = processResult.getData().getPayNodes().stream().filter(payNode -> payNode.getSerialNo().equals(1) && payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).min(Comparator.comparingInt(PayNodeBO::getBatchNo)).map(PayNodeBO::getPayRate).orElse(BigDecimal.ZERO);

        // c.校验商品的参数、价格、运费、金额等各种必须条件
        Wrapper<BuyerOrderCheckBO> checkResult = baseOrderProductService.checkAgentPurchaseOrderProduct(orderVO.getBuyerMemberId(), orderVO.getBuyerRoleId(), loginUser.getMemberLevelType(), orderVO, vendorProductMap.size(), processPayment, firstPayRate);
        if (checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        //对赠送优惠券进行skuId进行分组
        List<OrderGiveCouponDTO> orderGiveCouponDTOList = checkResult.getData().getOrderGiveCouponDTOList();
        Map<Long, List<OrderGiveCouponDTO>> giveCouponDTOList = orderGiveCouponDTOList.stream().collect(Collectors.groupingBy(OrderGiveCouponDTO::getSkuId));

        // d. 查询供应商Logo
        Wrapper<List<VendorLogoDTO>> logoResult = baseOrderService.checkVendorShopLogos(orderVO.getShopId(), orderVO.getProducts().stream().map(p -> new VendorBO(p.getVendorMemberId(), p.getVendorRoleId())).distinct().collect(Collectors.toList()));
        if (logoResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(logoResult.getCode(), logoResult.getMessage());
        }

        // e. 查询供应会员业务员用户Id
        Wrapper<List<OrderSalesDTO>> salesResult = baseOrderAuthService.findVendorSales(orderVO.getBuyerMemberId(), orderVO.getBuyerRoleId(), new ArrayList<>(vendorProductMap.keySet()));
        if (salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // f. 拆单条件
        // f-1: 按照供应商将订单商品分组
        Map<OrderSeparateDTO, List<MobileOrderProductVO>> vendorMap = baseOrderService.separateMobileOrder(orderVO.getProducts());

        // f-2: 计算分组之后的运费
        Map<OrderSeparateDTO, List<MobileOrderProductVO>> vendorFreightMap = baseOrderService.separateMobileOrder(checkResult.getData().getFreightProductList());
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(orderVO.getFreight(), vendorFreightMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> p.getDeliveryType().equals(OrderProductDeliverTypeEnum.LOGISTICS.getCode()) && p.getFreightType().equals(OrderFreightTypeEnum.BUYER.getCode())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // f-3: 计算分组之后的促销活动金额
        Map<OrderSeparateDTO, BigDecimal> vendorPriceMap = vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().map(p -> p.getRefPrice().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add)));
        Map<OrderSeparateDTO, BigDecimal> promotionMap = baseOrderPromotionService.findSeparateOrderPromotionAmount(orderVO.getPromotionAmount(), vendorPriceMap);

        // f-4: 计算分组之后的优惠券金额
        Map<OrderSeparateDTO, BigDecimal> couponMap = baseOrderCouponService.findSeparateOrderCouponAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getCouponMap());

        // f-5: 订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        //计算分组之后的积分抵扣金额
        Map<OrderSeparateDTO, BigDecimal> deductionMap = baseOrderDeductionService.findSeparateOrderDeductionAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getDeductionMap());

        //供应商积分抵扣比例
        Map<VendorBO, BigDecimal> pointsMap = baseOrderDeductionService.vendorCalculateDeductionPoints(orderVO.getDeductions());

        //计算分组之后的税费金额
        Map<OrderSeparateDTO, BigDecimal> taxesMap = baseOrderDeductionService.findSeparateOrderDeductionAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getTaxesMap());


        //是否需要支付、支付金额、支付次数
        boolean requirePayment = false;
        BigDecimal payAmount = BigDecimal.ZERO;
        Integer batchNo = 0;
        Integer fundMode = 0;
        //购物车Id列表
        List<Long> cartIds = new ArrayList<>();
        //生成的订单列表
        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<MobileOrderProductVO>> vendor : vendorMap.entrySet()) {
            //获取该供应商的订单送货时间、订单备注
            AtomicReference<String> deliverPeriod = new AtomicReference<>("");
            AtomicReference<String> remark = new AtomicReference<>("");
            if (!CollectionUtils.isEmpty(orderVO.getDeliverTimes())) {
                orderVO.getDeliverTimes().stream().filter(deliverTime -> deliverTime.getVendorMemberId().equals(vendor.getKey().getVendorMemberId()) && deliverTime.getVendorRoleId().equals(vendor.getKey().getVendorRoleId())).findFirst().ifPresent(deliverTimeVO -> {
                    deliverPeriod.set(StringUtils.hasLength(deliverTimeVO.getDeliverTime()) ? deliverTimeVO.getDeliverTime() : "");
                    remark.set(StringUtils.hasLength(deliverTimeVO.getRemark()) ? deliverTimeVO.getRemark() : "");
                });
            }

            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setSubmitTime(LocalDateTime.now());
            order.setDeliverPeriod(deliverPeriod.get());
            order.setBuyerMemberId(orderVO.getBuyerMemberId());
            order.setBuyerRoleId(orderVO.getBuyerRoleId());
            order.setBuyerMemberName(orderVO.getBuyerMemberName());
            //代客下单订单是“待分配”订单，所以不能设置采购商的用户Id
            order.setBuyerUserId(null);
            order.setVendorMemberId(loginUser.getMemberId());
            order.setVendorRoleId(loginUser.getMemberRoleId());
            order.setVendorMemberName(loginUser.getCompany());
            order.setVendorLogo(logoResult.getData().stream().filter(logo -> logo.getVendorMemberId().equals(vendor.getKey().getVendorMemberId()) && logo.getVendorRoleId().equals(vendor.getKey().getVendorRoleId())).findFirst().map(VendorLogoDTO::getLogo).orElse(""));
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            order.setStoreId(orderVO.getStoreId());

            order.setOrderKind(loginUser.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_WEB.getCode()) ? OrderSourceKindEnum.BUYER.getCode() : OrderSourceKindEnum.MOBILE_BUYER.getCode());
            order.setQuoteId(0L);
            order.setQuoteNo("");
            order.setLogisticsNo("");
            order.setDigest(vendor.getValue().stream().map(MobileOrderProductVO::getName).filter(StringUtils::hasLength).findFirst().orElse(""));
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //拆单、转单
            order.setSupplyMemberId(vendor.getKey().getSupplyMemberId());
            order.setSupplyRoleId(vendor.getKey().getSupplyRoleId());
            order.setSupplyMemberName(vendor.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);

            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkMobileOrderProduct(order, vendor.getValue(), checkResult.getData().getPlatformCouponMap());
            if (productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }


            //保存赠送优惠券信息
            baseOrderProductService.addGiveCouponList(order, vendor.getValue(), giveCouponDTOList);
            //添加购物车Id
            cartIds.addAll(productCheckResult.getData().getCartIds());

            // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
            if (productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            order.setPromotionAmount(promotionMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            order.setCouponAmount(couponMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            //App商品金额即订单金额（由于优惠金额在前端是根据“到手价”计算的，所以订单总金额不需要处理促销活动、优惠券金额）
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);
            //积分抵扣总金额
            order.setDeductionAmount(deductionMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            //税费
            order.setTaxes(taxesMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));

            order.setOrderMode(orderTypeMode.getOrderMode());
            //有税费，则为跨境电商进口类型
            order.setOrderType(crossBorders.get(0) ? OrderTypeEnum.COMMERCE_IMPORT.getCode() : orderTypeMode.getOrderType());

            //工作流任务
            order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

            //执行审核工作流
            Wrapper<ProcessTaskBO> taskResult = processResult.getData().getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
            if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<OrderPaymentCheckBO> paymentResult = baseOrderPaymentService.checkOrderPayment(order, orderVO.getPayType(), orderVO.getPayChannel(), processResult.getData().getPayNodes());
            if (paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //判断、执行支付任务
            Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
            if (payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
            }

            //合同信息
            Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), true);
            if (contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
            }

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if (invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
            if (consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            //优惠券
            Wrapper<Void> couponResult = baseOrderCouponService.checkOrderCoupons(order, orderVO.getCoupons());
            if (couponResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(couponResult.getCode(), couponResult.getMessage());
            }

            //积分抵扣
            Wrapper<Void> deductionResult = baseOrderDeductionService.checkOrderDeduction(order, orderVO.getDeductions(), pointsMap);
            if (deductionResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(deductionResult.getCode(), deductionResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRemark(order, remark.get(), true);
            if (requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //扣减库存
            Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
            if (deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            //由于合并下单时，支付次数和支付比例设置必须是一样的，所以“是否支付”，“支付次数”也是相同的
            requirePayment = payTaskResult.getData().getRequirePayment();
            fundMode = paymentResult.getData().getFundMode();
            batchNo = payTaskResult.getData().getBatchNo();
            payAmount = payAmount.add(payTaskResult.getData().getPayAmount());

            //更新供应商用户Id
            baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

            orders.add(order);
        }

        // 批量保存订单
        orderRepository.saveAll(orders);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(orders);

        //Last Step : 订单创建完成后:
        // 通知搜索服务，删除购物车
        baseOrderService.emptyProductCarts(orderVO.getShopType(), cartIds);

        List<OrderIdBO> orderIds = orders.stream().map(order -> new OrderIdBO(order.getId(), order.getOrderNo())).collect(Collectors.toList());

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), orderIds, OrderOperationEnum.CREATE, orders.get(0).getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(orderIds, loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getCompany(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, orders.get(0).getOuterStatus(), OrderOuterStatusEnum.getNameByCode(orders.get(0).getOuterStatus()), "");

        orders.forEach(order -> {
            // 通知报表服务，统计供应商的订单金额
            baseOrderService.reportVendorOrderAmount(order);
            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            //线下支付不用统计供应商待确认支付结果订单数据(上传完凭证才统计)
            if (!orderVO.getPayType().equals(OrderPayTypeEnum.OFFLINE_PAYMENT.getCode())) {
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());
            }
            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        //订单创建完成后，通知营销服务，扣减营销活动、优惠券使用记录
        baseOrderService.notifyPromotions(orders);

        //修改订单时删除原订单
        if (orderVO.getOrderId() != null) {
            orderRepository.deleteById(orderVO.getOrderId());
        }

        return Wrapper.success(new OrderCompleteVO(orders.stream().map(OrderDO::getId).collect(Collectors.toList()), requirePayment, fundMode, batchNo, orderVO.getPayType(), orderVO.getPayChannel(), payAmount));
    }

    /**
     * 进货单下单 - 创建采购订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createMobileBuyerOrder(HttpHeaders headers, BuyerOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromMobile(headers);
        return createBuyerOrder(loginUser, orderVO);
    }

    /**
     * 进货单下单 - 创建采购订单
     *
     * @param loginUser 登录用户
     * @param orderVO   接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createBuyerOrder(UserLoginCacheDTO loginUser, BuyerOrderVO orderVO) {
        //Step 1: 规则校验
        // a. 会员不能购买自己的商品
        if(orderVO.getProducts().stream().anyMatch(vendorProduct -> vendorProduct.getVendorMemberId().equals(loginUser.getMemberId()))) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        //b. 跨境商品不能与其他商品一起下单
        List<Boolean> crossBorders = orderVO.getProducts().stream().map(MobileOrderProductVO::getCrossBorder).distinct().collect(Collectors.toList());
        if(crossBorders.size() > 1) {
            return Wrapper.fail(ResponseCode.ORDER_PRODUCT_TRADE_PROCESS_IS_DIFFERENT);
        }

        //b.校验供应商的交易流程规则配置
        Map<VendorBO, List<MobileOrderProductVO>> vendorProductMap = orderVO.getProducts().stream().collect(Collectors.groupingBy(product -> new VendorBO(product.getVendorMemberId(), product.getVendorRoleId())));
        List<VendorProductBO> vendorProducts = vendorProductMap.entrySet().stream().map(entry -> {
            VendorProductBO vendorProduct = new VendorProductBO();
            vendorProduct.setVendorMemberId(entry.getKey().getVendorMemberId());
            vendorProduct.setVendorRoleId(entry.getKey().getVendorRoleId());
            vendorProduct.setProducts(entry.getValue().stream().map(p -> new OrderProductBO(p.getProductId(), p.getSkuId())).collect(Collectors.toList()));
            return vendorProduct;
        }).collect(Collectors.toList());

        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getShopId(), crossBorders.get(0) ? OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT : OrderTradeProcessTypeEnum.ORDER_TRADE, vendorProducts);
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //交易流程是否需要支付、第一次支付的比例
        boolean processPayment = processResult.getData().getPayTimes().compareTo(0) > 0;
        BigDecimal firstPayRate = processResult.getData().getPayNodes().stream().filter(payNode -> payNode.getSerialNo().equals(1) && payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).min(Comparator.comparingInt(PayNodeBO::getBatchNo)).map(PayNodeBO::getPayRate).orElse(BigDecimal.ZERO);

        // c.校验商品的参数、价格、运费、金额等各种必须条件
        Wrapper<BuyerOrderCheckBO> checkResult = baseOrderProductService.checkMobileOrderProductPrices(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getMemberLevelType(), orderVO, vendorProductMap.size(), processPayment, firstPayRate);
        if(checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        //对赠送优惠券进行skuId进行分组
        List<OrderGiveCouponDTO> orderGiveCouponDTOList = checkResult.getData().getOrderGiveCouponDTOList();
        Map<Long, List<OrderGiveCouponDTO>> giveCouponDTOList = orderGiveCouponDTOList.stream().collect(Collectors.groupingBy(OrderGiveCouponDTO::getSkuId));

        // d. 查询供应商Logo
        Wrapper<List<VendorLogoDTO>> logoResult = baseOrderService.checkVendorShopLogos(orderVO.getShopId(), orderVO.getProducts().stream().map(p -> new VendorBO(p.getVendorMemberId(), p.getVendorRoleId())).distinct().collect(Collectors.toList()));
        if(logoResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(logoResult.getCode(), logoResult.getMessage());
        }

        // e. 查询供应会员业务员用户Id
        Wrapper<List<OrderSalesDTO>> salesResult = baseOrderAuthService.findVendorSales(loginUser.getMemberId(), loginUser.getMemberRoleId(), new ArrayList<>(vendorProductMap.keySet()));
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // f. 拆单条件
        // f-1: 按照供应商将订单商品分组
        Map<OrderSeparateDTO, List<MobileOrderProductVO>> vendorMap = baseOrderService.separateMobileOrder(orderVO.getProducts());

        // f-2: 计算分组之后的运费
        Map<OrderSeparateDTO, List<MobileOrderProductVO>> vendorFreightMap = baseOrderService.separateMobileOrder(checkResult.getData().getFreightProductList());
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(orderVO.getFreight(), vendorFreightMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> p.getDeliveryType().equals(OrderProductDeliverTypeEnum.LOGISTICS.getCode()) && p.getFreightType().equals(OrderFreightTypeEnum.BUYER.getCode())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // f-3: 计算分组之后的促销活动金额
        Map<OrderSeparateDTO, BigDecimal> vendorPriceMap = vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().map(p -> p.getRefPrice().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add)));
        Map<OrderSeparateDTO, BigDecimal> promotionMap = baseOrderPromotionService.findSeparateOrderPromotionAmount(orderVO.getPromotionAmount(), vendorPriceMap);

        // f-4: 计算分组之后的优惠券金额
        Map<OrderSeparateDTO, BigDecimal> couponMap = baseOrderCouponService.findSeparateOrderCouponAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getCouponMap());

        // f-5: 订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        //计算分组之后的积分抵扣金额
        Map<OrderSeparateDTO, BigDecimal> deductionMap = baseOrderDeductionService.findSeparateOrderDeductionAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getDeductionMap());

        //供应商积分抵扣比例
        Map<VendorBO, BigDecimal> pointsMap = baseOrderDeductionService.vendorCalculateDeductionPoints(orderVO.getDeductions());

        //计算分组之后的税费金额
        Map<OrderSeparateDTO, BigDecimal> taxesMap = baseOrderDeductionService.findSeparateOrderDeductionAmount(vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().stream().map(MobileOrderProductVO::getSkuId).collect(Collectors.toList()))), checkResult.getData().getTaxesMap());


        //是否需要支付、支付金额、支付次数
        boolean requirePayment = false;
        BigDecimal payAmount = BigDecimal.ZERO;
        Integer batchNo = 0;
        Integer fundMode = 0;
        //购物车Id列表
        List<Long> cartIds = new ArrayList<>();
        //生成的订单列表
        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<MobileOrderProductVO>> vendor : vendorMap.entrySet()) {
            //获取该供应商的订单送货时间、订单备注
            AtomicReference<String> deliverPeriod = new AtomicReference<>("");
            AtomicReference<String> remark = new AtomicReference<>("");
            if(!CollectionUtils.isEmpty(orderVO.getDeliverTimes())) {
                orderVO.getDeliverTimes().stream().filter(deliverTime -> deliverTime.getVendorMemberId().equals(vendor.getKey().getVendorMemberId()) && deliverTime.getVendorRoleId().equals(vendor.getKey().getVendorRoleId())).findFirst().ifPresent(deliverTimeVO -> {
                    deliverPeriod.set(StringUtils.hasLength(deliverTimeVO.getDeliverTime()) ? deliverTimeVO.getDeliverTime() : "");
                    remark.set(StringUtils.hasLength(deliverTimeVO.getRemark()) ? deliverTimeVO.getRemark() : "");
                });
            }

            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setSubmitTime(LocalDateTime.now());
            order.setDeliverPeriod(deliverPeriod.get());
            order.setBuyerMemberId(loginUser.getMemberId());
            order.setBuyerRoleId(loginUser.getMemberRoleId());
            order.setBuyerUserId(loginUser.getUserId());
            order.setBuyerMemberName(loginUser.getCompany());
            order.setVendorMemberId(vendor.getKey().getVendorMemberId());
            order.setVendorRoleId(vendor.getKey().getVendorRoleId());
            order.setVendorMemberName(vendor.getKey().getVendorMemberName());
            order.setVendorLogo(logoResult.getData().stream().filter(logo -> logo.getVendorMemberId().equals(vendor.getKey().getVendorMemberId()) && logo.getVendorRoleId().equals(vendor.getKey().getVendorRoleId())).findFirst().map(VendorLogoDTO::getLogo).orElse(""));
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            order.setStoreId(orderVO.getStoreId());

            order.setOrderKind(loginUser.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_WEB.getCode()) ? OrderSourceKindEnum.BUYER.getCode() : OrderSourceKindEnum.MOBILE_BUYER.getCode());
            order.setQuoteId(0L);
            order.setQuoteNo("");
            order.setLogisticsNo("");
            order.setDigest(vendor.getValue().stream().map(MobileOrderProductVO::getName).filter(StringUtils::hasLength).findFirst().orElse(""));
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //拆单、转单
            order.setSupplyMemberId(vendor.getKey().getSupplyMemberId());
            order.setSupplyRoleId(vendor.getKey().getSupplyRoleId());
            order.setSupplyMemberName(vendor.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);

            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkMobileOrderProduct(order, vendor.getValue(), checkResult.getData().getPlatformCouponMap());
            if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }


            //保存赠送优惠券信息
            baseOrderProductService.addGiveCouponList(order,vendor.getValue(),giveCouponDTOList);
            //添加购物车Id
            cartIds.addAll(productCheckResult.getData().getCartIds());

            // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
            if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            order.setPromotionAmount(promotionMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            order.setCouponAmount(couponMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            //App商品金额即订单金额（由于优惠金额在前端是根据“到手价”计算的，所以订单总金额不需要处理促销活动、优惠券金额）
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);
            //积分抵扣总金额
            order.setDeductionAmount(deductionMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));
            //税费
            order.setTaxes(taxesMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO));

            order.setOrderMode(orderTypeMode.getOrderMode());
            //有税费，则为跨境电商进口类型
            order.setOrderType(crossBorders.get(0) ? OrderTypeEnum.COMMERCE_IMPORT.getCode() : orderTypeMode.getOrderType());

            //工作流任务
            order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

            //执行审核工作流
            Wrapper<ProcessTaskBO> taskResult = processResult.getData().getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<OrderPaymentCheckBO> paymentResult = baseOrderPaymentService.checkOrderPayment(order, orderVO.getPayType(), orderVO.getPayChannel(), processResult.getData().getPayNodes());
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //判断、执行支付任务
            Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
            if(payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
            }

            //合同信息
            Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), true);
            if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
            }

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
            if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            //优惠券
            Wrapper<Void> couponResult = baseOrderCouponService.checkOrderCoupons(order, orderVO.getCoupons());
            if(couponResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(couponResult.getCode(), couponResult.getMessage());
            }

            //积分抵扣
            Wrapper<Void> deductionResult = baseOrderDeductionService.checkOrderDeduction(order, orderVO.getDeductions(), pointsMap);
            if (deductionResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(deductionResult.getCode(), deductionResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRemark(order, remark.get(), true);
            if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //扣减库存
            Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
            if(deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            //由于合并下单时，支付次数和支付比例设置必须是一样的，所以“是否支付”，“支付次数”也是相同的
            requirePayment = payTaskResult.getData().getRequirePayment();
            fundMode = paymentResult.getData().getFundMode();
            batchNo = payTaskResult.getData().getBatchNo();
            payAmount = payAmount.add(payTaskResult.getData().getPayAmount());

            //更新供应商用户Id
            baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

            orders.add(order);
        }

        // 批量保存订单
        orderRepository.saveAll(orders);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(orders);

        //Last Step : 订单创建完成后:
        // 通知搜索服务，删除购物车
        baseOrderService.emptyProductCarts(orderVO.getShopType(), cartIds);

        List<OrderIdBO> orderIds = orders.stream().map(order -> new OrderIdBO(order.getId(), order.getOrderNo())).collect(Collectors.toList());

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), orderIds, OrderOperationEnum.CREATE, orders.get(0).getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(orderIds, loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getCompany(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, orders.get(0).getOuterStatus(), OrderOuterStatusEnum.getNameByCode(orders.get(0).getOuterStatus()), "");

        orders.forEach(order -> {
            // 通知报表服务，统计供应商的订单金额
            baseOrderService.reportVendorOrderAmount(order);
            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            //线下支付不用统计供应商待确认支付结果订单数据(上传完凭证才统计)
            if(!orderVO.getPayType().equals(OrderPayTypeEnum.OFFLINE_PAYMENT.getCode())){
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());
            }
            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        //订单创建完成后，通知营销服务，扣减营销活动、优惠券使用记录
        baseOrderService.notifyPromotions(orders);

        return Wrapper.success(new OrderCompleteVO(orders.stream().map(OrderDO::getId).collect(Collectors.toList()), requirePayment, fundMode, batchNo, orderVO.getPayType(), orderVO.getPayChannel(), payAmount));
    }

    /**
     * Web - 创建拼团订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createGroupOrder(HttpHeaders headers, BuyerOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return createGroupOrder(loginUser, orderVO);
    }

    /**
     * App - 创建拼团订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createMobileGroupOrder(HttpHeaders headers, BuyerOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromMobile(headers);
        return createGroupOrder(loginUser, orderVO);
    }

    /**
     * 创建拼团订单
     *
     * @param loginUser 登录用户
     * @param orderVO   接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createGroupOrder(UserLoginCacheDTO loginUser, BuyerOrderVO orderVO) {
        //Step 1: 规则校验
        // a. 会员不能购买自己的商品
        if(orderVO.getProducts().stream().anyMatch(vendorProduct -> vendorProduct.getVendorMemberId().equals(loginUser.getMemberId()))) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        Long vendorMemberId = orderVO.getProducts().get(0).getVendorMemberId();
        Long vendorRoleId = orderVO.getProducts().get(0).getVendorRoleId();
        String vendorMemberName = orderVO.getProducts().get(0).getVendorMemberName();

        //b.校验供应商的交易流程规则配置
        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(vendorMemberId, vendorRoleId, orderVO.getShopId(), OrderTradeProcessTypeEnum.ORDER_TRADE, orderVO.getProducts().stream().map(p -> new OrderProductBO(p.getProductId(), p.getSkuId())).collect(Collectors.toList()));
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //交易流程是否需要支付、第一次支付的比例
        boolean processPayment = processResult.getData().getPayTimes().compareTo(0) > 0;
        BigDecimal firstPayRate = processResult.getData().getPayNodes().stream().filter(payNode -> payNode.getSerialNo().equals(1) && payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).min(Comparator.comparingInt(PayNodeBO::getBatchNo)).map(PayNodeBO::getPayRate).orElse(BigDecimal.ZERO);

        // c.校验商品的参数、价格、运费、金额等各种必须条件
        Wrapper<Long> checkResult = baseOrderProductService.checkMobileGroupOrderProductPrices(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getMemberLevelType(), orderVO, processPayment, firstPayRate);
        if(checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        // d. 查询供应商Logo
        Wrapper<VendorLogoDTO> logoResult = baseOrderService.checkVendorShopLogo(orderVO.getShopId(), vendorMemberId, vendorRoleId);
        if(logoResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(logoResult.getCode(), logoResult.getMessage());
        }

        // e. 查询供应商业务员用户Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(loginUser.getMemberId(), loginUser.getMemberRoleId(), vendorMemberId, vendorRoleId);
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // f: 订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        //创建订单
        OrderDO order = new OrderDO();
        order.setCreateTime(LocalDateTime.now());
        order.setSubmitTime(LocalDateTime.now());
        order.setDeliverPeriod(CollectionUtils.isEmpty(orderVO.getDeliverTimes()) ? "" : orderVO.getDeliverTimes().stream().filter(deliverTime -> deliverTime.getVendorMemberId().equals(vendorMemberId) && deliverTime.getVendorRoleId().equals(vendorRoleId) && StringUtils.hasLength(deliverTime.getDeliverTime())).map(BuyerOrderDeliverTimeVO::getDeliverTime).findFirst().orElse(""));
        order.setBuyerMemberId(loginUser.getMemberId());
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerUserId(loginUser.getUserId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(vendorMemberId);
        order.setVendorRoleId(vendorRoleId);
        order.setVendorMemberName(vendorMemberName);
        order.setVendorLogo(logoResult.getData().getLogo());
        order.setOrderNo(OrderStringUtil.randomUniqueNumber());
        order.setShopId(orderVO.getShopId());
        order.setShopType(orderVO.getShopType());
        order.setShopEnvironment(orderVO.getShopEnvironment());
        order.setShopName(orderVO.getShopName());

        order.setOrderMode(orderTypeMode.getOrderMode());
        order.setOrderType(orderTypeMode.getOrderType());

        order.setOrderKind(OrderSourceKindEnum.GROUP.getCode());
        order.setQuoteId(0L);
        order.setQuoteNo("");
        order.setLogisticsNo("");
        order.setDigest(orderVO.getProducts().stream().map(MobileOrderProductVO::getName).filter(StringUtils::hasLength).findFirst().orElse(""));
        order.setHasRefund(false);
        order.setHasPaid(false);
        order.setHasDelivered(false);
        order.setHasReceived(false);
        order.setBuyerCommented(false);
        order.setVendorCommented(false);
        //拆单、转单
        order.setSupplyMemberId(0L);
        order.setSupplyRoleId(0L);
        order.setSupplyMemberName("");
        //在转单的时候再改变拆单类型，生成关联的订单Id
        order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
        order.setRelationId(0L);
        order.setRelationNo("");
        //营销活动状态
        order.setPromotionStatus(OrderPromotionStatusEnum.GROUPING.getCode());
        //拼团Id
        order.setGroupId(checkResult.getData());

        // 保存订单，以生成订单的Id
        orderRepository.saveAndFlush(order);

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkMobileGroupOrderProduct(order, orderVO.getProducts());
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(orderVO.getFreight());
        order.setPromotionAmount(orderVO.getPromotionAmount());
        order.setCouponAmount(BigDecimal.ZERO);
        //拼团订单金额 = Σ(商品到手价 * 数量） + 运费
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).setScale(2, RoundingMode.HALF_UP));
        order.setPaidAmount(BigDecimal.ZERO);

        //工作流任务
        order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

        //执行审核工作流
        Wrapper<ProcessTaskBO> taskResult = processResult.getData().getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        // 支付记录
        Wrapper<OrderPaymentCheckBO> paymentResult = baseOrderPaymentService.checkOrderPayment(order, orderVO.getPayType(), orderVO.getPayChannel(), processResult.getData().getPayNodes());
        if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
        }

        //是否满足退款条件
        order.setCanRefund(paymentResult.getData().getCanRefund());

        //判断、执行支付任务
        Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
        if(payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
        }

        Boolean requirePayment = payTaskResult.getData().getRequirePayment();
        Integer fundMode = paymentResult.getData().getFundMode();
        Integer batchNo = payTaskResult.getData().getBatchNo();
        BigDecimal payAmount =payTaskResult.getData().getPayAmount();

        //合同信息
        Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), true);
        if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 拼团订单不能使用优惠券
        order.setCoupons(new HashSet<>());

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRemark(order, CollectionUtils.isEmpty(orderVO.getDeliverTimes()) ? "" : orderVO.getDeliverTimes().stream().filter(d -> d.getVendorMemberId().equals(vendorMemberId) && d.getVendorRoleId().equals(vendorRoleId)).map(BuyerOrderDeliverTimeVO::getRemark).findFirst().orElse(""), true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        //发货记录
        order.setDeliveries(new HashSet<>());

        //扣减库存
        Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
        if(deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
        }

        //更新供应商用户Id字段
        baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

        // 保存订单
        orderRepository.saveAndFlush(order);

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getCompany(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        // 通知报表服务，统计供应商的订单金额
        baseOrderService.reportVendorOrderAmount(order);
        // 通知报表服务，统计采购商、供应商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
        baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());
        // 通知报表服务，发送采购商、供应商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
        baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

        //订单创建完成后，通知营销服务，扣减营销活动、优惠券使用记录
        baseOrderService.notifyPromotions(Collections.singletonList(order));

        return Wrapper.success(new OrderCompleteVO(Collections.singletonList(order.getId()), requirePayment, fundMode, batchNo, orderVO.getPayType(), orderVO.getPayChannel(), payAmount));
    }


    /**
     * 积分商城 - 创建积分订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createPointsOrder(HttpHeaders headers, BuyerPointsOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return createPointsOrder(loginUser, orderVO);
    }

    /**
     * App - 创建积分订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createMobilePointsOrder(HttpHeaders headers, BuyerPointsOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromMobile(headers);
        return createPointsOrder(loginUser, orderVO);
    }

    /**
     * 创建积分订单
     *
     * @param loginUser 登录用户
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<OrderCompleteVO> createPointsOrder(UserLoginCacheDTO loginUser, BuyerPointsOrderVO orderVO) {
        //Step 1: 规则校验
        // a. 会员不能购买自己的商品
        if(orderVO.getVendorMemberId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // b.校验供应商的交易流程规则配置
        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getShopId(), OrderTradeProcessTypeEnum.RIGHT_POINT, Stream.of(new OrderProductBO(orderVO.getProduct().getProductId(), orderVO.getProduct().getSkuId())).collect(Collectors.toList()));
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        // c. 查询供应会员业务员用户Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(loginUser.getMemberId(), loginUser.getMemberRoleId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId());
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // d.订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        //创建订单
        OrderDO order = new OrderDO();
        order.setCreateTime(LocalDateTime.now());
        order.setSubmitTime(LocalDateTime.now());
        order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");
        order.setBuyerMemberId(loginUser.getMemberId());
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerUserId(loginUser.getUserId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setVendorLogo(baseOrderService.findVendorMemberLogo(orderVO.getVendorMemberId()));
        order.setOrderNo(OrderStringUtil.randomUniqueNumber());
        order.setShopId(orderVO.getShopId());
        order.setShopType(orderVO.getShopType());
        order.setShopEnvironment(orderVO.getShopEnvironment());
        order.setShopName(orderVO.getShopName());
        order.setOrderMode(orderTypeMode.getOrderMode());
        order.setOrderType(orderTypeMode.getOrderType());
        order.setOrderKind(loginUser.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_WEB.getCode()) ? OrderSourceKindEnum.RIGHT_POINT.getCode() : OrderSourceKindEnum.MOBILE_RIGHT_POINT.getCode());
        order.setQuoteId(0L);
        order.setQuoteNo("");
        order.setLogisticsNo("");
        order.setDigest(orderVO.getProduct().getName());
        order.setCanRefund(false);
        order.setHasRefund(false);
        order.setHasPaid(false);
        order.setHasDelivered(false);
        order.setHasReceived(false);
        order.setBuyerCommented(false);
        order.setVendorCommented(false);
        //积分订单没有拆单、转单
        order.setSupplyMemberId(0L);
        order.setSupplyRoleId(0L);
        order.setSupplyMemberName("");
        order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
        order.setRelationId(0L);
        order.setRelationNo("");
        //营销活动状态
        order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
        order.setGroupId(0L);

        // 保存订单，以生成订单的Id
        orderRepository.saveAndFlush(order);

        //检查商品信息，获得订单总积分（总金额）
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkPointsOrderProduct(order, orderVO.getProduct());
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        //积分兑换订单运费为0
        order.setFreight(BigDecimal.ZERO);
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
        order.setPaidAmount(BigDecimal.ZERO);

        //工作流任务
        order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

        //执行工作流
        Wrapper<ProcessTaskBO> taskResult = processResult.getData().getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //更新供应商用户Id
        baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

        // 支付记录
        Wrapper<Integer> paymentResult = baseOrderPaymentService.checkPointsOrderPayment(order, OrderPayTypeEnum.MEMBER_RIGHT.getCode(), OrderPayChannelEnum.RIGHT_POINT.getCode(), processResult.getData().getPayNodes());
        if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
        }

        //判断、执行支付任务
        Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
        if(payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
        }

        //下单后返回的信息
        boolean requirePayment = payTaskResult.getData().getRequirePayment();
        Integer fundMode = paymentResult.getData();
        Integer batchNo = payTaskResult.getData().getBatchNo();
        BigDecimal payAmount = payTaskResult.getData().getPayAmount();

        //合同信息（积分订单没有合同）
        Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, null, true);
        if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求：积分订单没有
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, null, true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        //扣减库存
        Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
        if(deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
        }

        //发货记录
        order.setDeliveries(new HashSet<>());

        // 保存订单
        orderRepository.saveAndFlush(order);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(order.getId(), processResult.getData().getExpireHours());

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getCompany(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        // 通知报表服务，统计采购商、供应商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
        baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());
        // 通知消息服务，发送采购商、供应商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
        baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

        return Wrapper.success(new OrderCompleteVO(Stream.of(order.getId()).collect(Collectors.toList()), requirePayment, fundMode, batchNo, OrderPayTypeEnum.MEMBER_RIGHT.getCode(), OrderPayChannelEnum.RIGHT_POINT.getCode(), payAmount));
    }

    /**
     * 订单支付
     *
     * @param headers HttpHeader信息
     * @param payVO   接口参数
     * @return 支付链接（在线支付）
     */
    @Override
    public Wrapper<PayResultDetailVO> orderPay(HttpHeaders headers, BuyerMergePayVO payVO) {
        return buyerOrderService.orderPay(headers, payVO);
    }

    /**
     * 查询支付结果
     *
     * @param headers  HttpHeader信息
     * @param resultVO 接口参数
     * @return 支付结果
     */
    @Override
    public Wrapper<BuyerPayResultDetailVO> findPayResult(HttpHeaders headers, BuyerPayResultVO resultVO) {
        return buyerOrderService.findPayResult(headers, resultVO);
    }

    /**
     * 采购订单 - 新增SRM订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> createSrmOrder(HttpHeaders headers, BuyerSrmOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        //每个物料的金额不能大于合同剩余金额
        if (!orderVO.getProducts().stream().allMatch(p -> p.getPrice().multiply(p.getQuantity()).compareTo(orderVO.getContract().getLeftAmount()) <= 0)) {
            return Wrapper.fail(ResponseCode.ORDER_MATERIAL_PRICE_GT_NOT_CONTRACT_BALANCE);
        }

        //规则校验：
        // a. 会员不能购买自己的商品
        if(loginUser.getMemberId().equals(orderVO.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // b. 校验采购流程规则配置
        Wrapper<OrderPurchaseProcessBO> processResult = baseOrderProcessService.findBuyerPurchaseProcess(loginUser.getMemberId(), loginUser.getMemberRoleId(), OrderPurchaseProcessTypeEnum.ORDER_TRADE, Collections.singletonList(orderVO.getContract().getContractId()));
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //创建订单
        OrderDO order = new OrderDO();
        order.setCreateTime(LocalDateTime.now());
        order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");
        order.setBuyerMemberId(loginUser.getMemberId());
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerUserId(loginUser.getUserId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setVendorLogo(baseOrderService.findVendorMemberLogo(orderVO.getVendorMemberId()));
        order.setOrderNo(OrderStringUtil.randomUniqueNumber());
        //Srm订单没有商城
        order.setShopId(0L);
        order.setShopType(0);
        order.setShopEnvironment(0);
        order.setShopName("");
        order.setOrderMode(orderVO.getOrderMode());
        order.setOrderType(OrderModeEnum.getOrderTypeByCode(orderVO.getOrderMode()));
        order.setOrderKind(OrderSourceKindEnum.SRM.getCode());
        order.setQuoteId(0L);
        order.setQuoteNo("");
        order.setLogisticsNo("");
        order.setDigest(orderVO.getDigest());
        order.setCanRefund(false);
        order.setHasRefund(false);
        order.setHasPaid(false);
        order.setHasDelivered(false);
        order.setHasReceived(false);
        order.setBuyerCommented(false);
        order.setVendorCommented(false);
        //拆单、转单
        order.setSupplyMemberId(0L);
        order.setSupplyRoleId(0L);
        order.setSupplyMemberName("");
        order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
        order.setRelationId(0L);
        order.setRelationNo("");
        //营销活动状态
        order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
        order.setGroupId(0L);
        // 保存订单，以生成订单的Id
        orderRepository.saveAndFlush(order);

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkSrmOrderProduct(order, orderVO.getProducts(), true);
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
        if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(BigDecimal.ZERO);
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
        order.setPaidAmount(BigDecimal.ZERO);

        //工作流任务
        OrderProcessTaskDO processTask = new OrderProcessTaskDO();
        processTask.setProcessKey(processResult.getData().getProcessKey());
        processTask.setTaskId("");
        processTask.setPayTimes(0);
        processTask.setExpireHours(BigDecimal.ZERO);
        processTask.setSkipFirstStep(processResult.getData().getSkipFirstStep());
        processTask.setProcessType(OrderProcessTypeEnum.PURCHASE.getCode());
        processTask.setNextPay(false);
        processTask.setPayStartNode(0);
        processTask.setPayEndNode(0);
        order.setTask(processTask);

        //执行审核工作流（注意这里是直接启动）
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.startOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //合同信息
        Wrapper<Void> contractResult = baseOrderContractService.checkSrmOrderContract(order, orderVO.getContract(), true);
        if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getHasInvoice(), orderVO.getInvoice(), true);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        ////SRM订单无需支付，发货记录
        order.setPayments(new HashSet<>());
        order.setDeliveries(new HashSet<>());

        // 保存订单
        orderRepository.saveAndFlush(order);

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        // 统计采购商、供应商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
        baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

        // 发送采购商、供应商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
        baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

        return Wrapper.success();
    }

    /**
     * 采购订单 - 修改SRM订单
     *
     * @param headers  HttpHeader信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateSrmOrder(HttpHeaders headers, BuyerSrmOrderUpdateVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(orderVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //规则校验：
        //如果不为“待提交”状态，不允许修改
        if(!order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_STATUS_IS_NOT_MATCHED);
        }

        //创建订单
        order.setBuyerMemberId(loginUser.getMemberId());
        order.setDeliverPeriod(Optional.ofNullable(orderVO.getDeliverDate()).orElse(""));
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setOrderType(OrderModeEnum.getOrderTypeByCode(orderVO.getOrderMode()));
        order.setOrderMode(orderVO.getOrderMode());
        order.setDigest(orderVO.getDigest());

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkSrmOrderProduct(order, orderVO.getProducts(), false);
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
        if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(BigDecimal.ZERO);
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));

        //合同信息
        Wrapper<Void> contractResult = baseOrderContractService.checkSrmOrderContract(order, orderVO.getContract(), false);
        if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getHasInvoice(), orderVO.getInvoice(), false);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), false);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        //支付记录，发货记录
        order.setPayments(new HashSet<>());
        order.setDeliveries(new HashSet<>());

        // 保存订单
        orderRepository.saveAndFlush(order);

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.MODIFY, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.MODIFY, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        return Wrapper.success();
    }

    /**
     * 采购订单 - 新增B2B订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> createBusinessOrder(HttpHeaders headers, BuyerBusinessOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        //规则校验：
        // a. 会员不能购买自己的商品
        if(loginUser.getMemberId().equals(orderVO.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // b.订单模式
        if(!orderVO.getOrderMode().equals(OrderModeEnum.QUOTATION.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_MODE_MISMATCHED);
        }

        // c. 拆单规则
        Map<OrderSeparateDTO, List<BusinessOrderProductVO>> vendorMap = baseOrderService.separateBusinessOrder(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getVendorMemberName(), orderVO.getProducts());

        // d. 拆单运费
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(orderVO.getFreight(), orderVO.getConsignee(), vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> NumberUtil.notNullAndPositive(p.getLogisticsTemplateId()) && NumberUtil.notNullAndPositive(p.getWeight()) && NumberUtil.notNullAndPositive(p.getQuantity())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // e.根据拆单后的分组，校验供应商的交易流程规则配置
        Map<OrderSeparateDTO, OrderTradeProcessBO> vendorTradeProcessMap = new HashMap<>();
        for (Map.Entry<OrderSeparateDTO, List<BusinessOrderProductVO>> entry : vendorMap.entrySet()) {
            Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(entry.getKey().getVendorMemberId(), entry.getKey().getVendorRoleId(), orderVO.getShopId(), OrderTradeProcessTypeEnum.ORDER_TRADE, entry.getValue().stream().map(product -> new OrderProductBO(product.getProductId(), product.getSkuId())).collect(Collectors.toList()));
            if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(processResult.getCode(), processResult.getMessage());
            }

            vendorTradeProcessMap.put(entry.getKey(), processResult.getData());
        }

        // f.从交易服务中，校验询价商品的价格
        Wrapper<Void> priceCheckResult = baseOrderProductService.checkBusinessOrderProductPrices(orderVO.getQuoteNo(), orderVO.getProducts());
        if(priceCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(priceCheckResult.getCode(), priceCheckResult.getMessage());
        }

        // g. 从店铺模板服务中，查询供应商Logo
        String vendorLogo = baseOrderService.findVendorShopLogo(orderVO.getShopId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId());

        //拆单
        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<BusinessOrderProductVO>> entry : vendorMap.entrySet()) {
            //交易流程
            OrderTradeProcessBO tradeProcess = vendorTradeProcessMap.getOrDefault(entry.getKey(), null);
            if(tradeProcess == null) {
                return Wrapper.fail(ResponseCode.ORDER_VENDOR_DOES_NOT_CONFIG_TRADE_PROCESS);
            }

            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");
            order.setBuyerMemberId(loginUser.getMemberId());
            order.setBuyerRoleId(loginUser.getMemberRoleId());
            order.setBuyerUserId(loginUser.getUserId());
            order.setBuyerMemberName(loginUser.getCompany());
            order.setVendorMemberId(orderVO.getVendorMemberId());
            order.setVendorRoleId(orderVO.getVendorRoleId());
            order.setVendorMemberName(orderVO.getVendorMemberName());
            order.setVendorLogo(vendorLogo);
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setLogisticsNo("");
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            //B2B下单模式为“进货单下单”，订单类型为“现货采购”
            order.setOrderMode(orderVO.getOrderMode());
            order.setOrderType(OrderModeEnum.getOrderTypeByCode(orderVO.getOrderMode()));
            order.setOrderKind(OrderSourceKindEnum.B2B.getCode());
            order.setQuoteId(orderVO.getQuoteId());
            order.setQuoteNo(orderVO.getQuoteNo());
            order.setDigest(StringUtils.hasText(orderVO.getDigest()) ? orderVO.getDigest() : entry.getValue().stream().filter(p -> StringUtils.hasLength(p.getName())).map(BusinessOrderProductVO::getName).findFirst().orElse(""));
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //拆单、转单
            order.setSupplyMemberId(entry.getKey().getSupplyMemberId());
            order.setSupplyRoleId(entry.getKey().getSupplyRoleId());
            order.setSupplyMemberName(entry.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);
            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkBusinessOrderProduct(order, entry.getValue(), true);
            if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(entry.getKey(), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setCouponAmount(BigDecimal.ZERO);
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);

            //工作流任务
            order.setTask(new OrderProcessTaskDO(tradeProcess, OrderProcessTypeEnum.TRADE.getCode()));

            //启动审核工作流
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.startOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<Void> paymentResult = baseOrderPaymentService.checkOrderCreatePayment(order, tradeProcess.getPayNodes(), orderVO.getPayments(), true);
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //合同信息
            Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), true);
            if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
            }

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
            if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
            if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            orders.add(order);
        }

        // 保存订单
        orderRepository.saveAll(orders);

        //Last Step : 订单创建完成后:
        orders.forEach(order -> {
            //内部流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        return Wrapper.success();
    }

    /**
     * “待新增订单” - 修改B2B订单
     *
     * @param headers  Http头部信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateBusinessOrder(HttpHeaders headers, BuyerBusinessOrderUpdateVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(orderVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //规则校验：
        //a. 如果不为“待提交”状态，不允许修改
        if(!order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_STATUS_IS_NOT_MATCHED);
        }

        // b. 会员不能购买自己的商品
        if(loginUser.getMemberId().equals(orderVO.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // c.校验供应商的交易流程规则配置
        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getShopId(), OrderTradeProcessTypeEnum.ORDER_TRADE, orderVO.getProducts().stream().map(product -> new OrderProductBO(product.getProductId(), product.getSkuId())).collect(Collectors.toList()));
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        // c.从交易服务中，校验询价商品的价格
        Wrapper<Void> priceCheckResult = baseOrderProductService.checkBusinessOrderProductPrices(orderVO.getQuoteNo(), orderVO.getProducts());
        if(priceCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(priceCheckResult.getCode(), priceCheckResult.getMessage());
        }

        // d.订单模式
        if(!orderVO.getOrderMode().equals(OrderModeEnum.QUOTATION.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_MODE_MISMATCHED);
        }

        //修改订单
        order.setCreateTime(LocalDateTime.now());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setShopId(orderVO.getShopId());
        order.setShopType(orderVO.getShopType());
        order.setShopEnvironment(orderVO.getShopEnvironment());
        order.setShopName(orderVO.getShopName());
        // 修改订单送货日期
        order.setDeliverPeriod(Optional.ofNullable(orderVO.getDeliverDate()).filter(StringUtils::hasLength).orElse(""));
        //B2B下单模式为“进货单下单”，订单类型为“现货采购”
        order.setOrderMode(orderVO.getOrderMode());
        order.setOrderType(OrderModeEnum.getOrderTypeByCode(orderVO.getOrderMode()));
        order.setOrderKind(OrderSourceKindEnum.B2B.getCode());
        order.setQuoteNo(orderVO.getQuoteNo());
        order.setDigest(orderVO.getDigest());
        order.setHasPaid(false);
        order.setHasDelivered(false);
        order.setHasReceived(false);

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkBusinessOrderProduct(order, orderVO.getProducts(), false);
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(orderVO.getFreight().setScale(2, RoundingMode.HALF_UP));
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
        order.setPaidAmount(BigDecimal.ZERO);

        // 支付记录
        Wrapper<Void> paymentResult = baseOrderPaymentService.checkOrderCreatePayment(order, processResult.getData().getPayNodes(), orderVO.getPayments(), false);
        if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
        }

        //合同信息
        Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), false);
        if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), false);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), false);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), false);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        // 保存订单
        orderRepository.saveAndFlush(order);

        //内外流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.MODIFY, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.MODIFY, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        return Wrapper.success();
    }

    /**
     * “新增现货采购订单” - 创建现货采购订单
     *
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> createPurchaseOrder(HttpHeaders headers, BuyerPurchaseOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        //跨境电商商品流程和普通订单流程判断
        List<Boolean> crossBorders = orderVO.getProducts().stream().map(product -> !Objects.isNull(product.getCrossBorder()) && product.getCrossBorder()).distinct().collect(Collectors.toList());
        if(crossBorders.size() > 1) {
            return Wrapper.fail(ResponseCode.ORDER_PRODUCT_TRADE_PROCESS_IS_DIFFERENT);
        }

        //规则校验：
        // a.校验供应商的交易流程规则配置
        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getShopId(), crossBorders.get(0) ? OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT : OrderTradeProcessTypeEnum.ORDER_TRADE, orderVO.getProducts().stream().map(product -> new OrderProductBO(product.getProductId(), product.getSkuId())).distinct().collect(Collectors.toList()));
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        // b.校验供应商商品的价格
        Wrapper<BigDecimal> priceCheckResult = baseOrderProductService.checkPurchaseOrderProductPrices(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getMemberType(), orderVO.getShopId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getProducts());
        if(priceCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(priceCheckResult.getCode(), priceCheckResult.getMessage());
        }

        // c. 查询商品运费
        Wrapper<BigDecimal> freightResult = baseOrderProductService.findPurchaseOrderFreight(orderVO.getConsignee(), orderVO.getProducts());
        if(freightResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(freightResult.getCode(), freightResult.getMessage());
        }

        // d. 供应商会员Logo
        String vendorLogo = baseOrderService.findVendorShopLogo(orderVO.getShopId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId());

        // d. 拆单条件
        // d-1: 按照供应商将订单商品分组
        Map<OrderSeparateDTO, List<PurchaseOrderProductVO>> vendorMap = baseOrderService.separatePurchaseOrder(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getVendorMemberName(), orderVO.getProducts());

        // d-2: 查询分组之后的运费
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(freightResult.getData(), vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> p.getDeliveryType().equals(OrderProductDeliverTypeEnum.LOGISTICS.getCode())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // d-3: 订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<PurchaseOrderProductVO>> entry : vendorMap.entrySet()) {
            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");
            order.setBuyerMemberId(loginUser.getMemberId());
            order.setBuyerRoleId(loginUser.getMemberRoleId());
            order.setBuyerUserId(loginUser.getUserId());
            order.setBuyerMemberName(loginUser.getCompany());
            order.setVendorMemberId(orderVO.getVendorMemberId());
            order.setVendorRoleId(orderVO.getVendorRoleId());
            order.setVendorMemberName(orderVO.getVendorMemberName());
            order.setVendorLogo(vendorLogo);
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setLogisticsNo("");
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            //下单模式、订单类型
            order.setOrderMode(orderTypeMode.getOrderMode());
            order.setOrderType(orderTypeMode.getOrderType());
            order.setOrderKind(OrderSourceKindEnum.BUYER.getCode());
            order.setQuoteId(0L);
            order.setQuoteNo("");
            order.setDigest(orderVO.getDigest());
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //拆单、转单
            order.setSupplyMemberId(entry.getKey().getSupplyMemberId());
            order.setSupplyRoleId(entry.getKey().getSupplyRoleId());
            order.setSupplyMemberName(entry.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);
            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkPurchaseOrderProduct(order, entry.getValue(), true);
            if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }

            // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
            if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(entry.getKey(), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setCouponAmount(BigDecimal.ZERO);
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);

            //工作流任务
            order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

            //启动工作流程
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.startOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<Void> paymentResult = baseOrderPaymentService.checkOrderCreatePayment(order, processResult.getData().getPayNodes(), orderVO.getPayments(), true);
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //合同信息
            order.setContract(null);

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkPurchaseOrderConsignee(order, orderVO.getConsignee(), true);
            if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
            if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            orders.add(order);
        }

        // 保存订单
        orderRepository.saveAll(orders);

        //Last Step : 订单创建完成后:
        orders.forEach(order -> {
            //内部流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        return Wrapper.success();
    }

    /**
     * “新增现货采购订单” - 修改现货采购订单
     *
     * @param headers  Http头部信息
     * @param orderVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> updatePurchaseOrder(HttpHeaders headers, BuyerPurchaseOrderUpdateVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(orderVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //修改订单
        order.setDigest(orderVO.getDigest());
        order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");

        // 支付记录
        Wrapper<Void> paymentResult = baseOrderPaymentService.updateOrderCreatePayment(order, orderVO.getPayments());
        if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), false);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkPurchaseOrderConsignee(order, orderVO.getConsignee(), false);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), false);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        orderRepository.saveAndFlush(order);

        //内外流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.MODIFY, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.MODIFY, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        return Wrapper.success();
    }

    /**
     * 新增请购单订单 - 新增订单
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 新增结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> createRequisitionOrder(HttpHeaders headers, RequisitionOrderCreateVO orderVO){
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        //规则校验：
        // a. 会员不能购买自己的商品
        if(loginUser.getMemberId().equals(orderVO.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // b. 校验采购流程规则配置 - 类型为“请购单”
        Wrapper<OrderPurchaseProcessBO> processResult = baseOrderProcessService.findBuyerPurchaseProcess(loginUser.getMemberId(), loginUser.getMemberRoleId(), OrderPurchaseProcessTypeEnum.REQUISITION, Collections.emptyList());
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //创建订单
        OrderDO order = new OrderDO();
        order.setCreateTime(LocalDateTime.now());
        order.setDeliverPeriod(StringUtils.hasLength(orderVO.getDeliverDate()) ? orderVO.getDeliverDate() : "");
        order.setBuyerMemberId(loginUser.getMemberId());
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerUserId(loginUser.getUserId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setVendorLogo(baseOrderService.findVendorMemberLogo(orderVO.getVendorMemberId()));
        order.setOrderNo(OrderStringUtil.randomUniqueNumber());
        order.setQuoteId(orderVO.getRequisitionId());
        order.setQuoteNo(orderVO.getRequisitionNo());
        //Srm订单没有商城
        order.setShopId(0L);
        order.setShopType(0);
        order.setShopEnvironment(0);
        order.setShopName("");
        order.setOrderMode(OrderModeEnum.REQUISITION.getCode());
        order.setOrderType(OrderTypeEnum.REQUISITION_TO_PURCHASE.getCode());
        order.setOrderKind(OrderSourceKindEnum.REQUISITION.getCode());
        order.setLogisticsNo("");
        order.setDigest(orderVO.getDigest());
        order.setCanRefund(false);
        order.setHasRefund(false);
        order.setHasPaid(false);
        order.setHasDelivered(false);
        order.setHasReceived(false);
        order.setBuyerCommented(false);
        order.setVendorCommented(false);
        //拆单、转单
        order.setSupplyMemberId(0L);
        order.setSupplyRoleId(0L);
        order.setSupplyMemberName("");
        order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
        order.setRelationId(0L);
        order.setRelationNo("");
        //营销活动状态
        order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
        order.setGroupId(0L);
        // 保存订单，以生成订单的Id
        orderRepository.save(order);

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkSrmOrderProduct(order, orderVO.getProducts(), true);
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
        if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(BigDecimal.ZERO);
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
        order.setPaidAmount(BigDecimal.ZERO);

        //工作流任务
        OrderProcessTaskDO processTask = new OrderProcessTaskDO();
        processTask.setProcessKey(processResult.getData().getProcessKey());
        processTask.setTaskId("");
        processTask.setPayTimes(0);
        processTask.setExpireHours(BigDecimal.ZERO);
        processTask.setSkipFirstStep(processResult.getData().getSkipFirstStep());
        processTask.setProcessType(OrderProcessTypeEnum.PURCHASE.getCode());
        processTask.setNextPay(false);
        processTask.setPayStartNode(0);
        processTask.setPayEndNode(0);
        order.setTask(processTask);

        //执行审核工作流（注意这里是直接启动）
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.startOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getHasInvoice(), orderVO.getInvoice(), true);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        ////SRM订单无需支付，发货记录
        order.setPayments(new HashSet<>());
        order.setDeliveries(new HashSet<>());

        // 保存订单
        orderRepository.save(order);

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

        // 统计采购商、供应商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
        baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

        // 发送采购商、供应商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
        baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        return Wrapper.success();
    }

    /**
     * 请购单订单 - 修改订单
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateRequisitionOrder(HttpHeaders headers, RequisitionOrderUpdateVO orderVO){
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(orderVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //规则校验：
        //如果不为“待提交”状态，不允许修改
        if(!order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_STATUS_IS_NOT_MATCHED);
        }

        //创建订单
        order.setBuyerMemberId(loginUser.getMemberId());
        // 更新送货时间
        order.setDeliverPeriod(Optional.ofNullable(orderVO.getDeliverDate()).filter(StringUtils::hasLength).orElse(""));
        order.setBuyerRoleId(loginUser.getMemberRoleId());
        order.setBuyerMemberName(loginUser.getCompany());
        order.setVendorMemberId(orderVO.getVendorMemberId());
        order.setVendorRoleId(orderVO.getVendorRoleId());
        order.setVendorMemberName(orderVO.getVendorMemberName());
        order.setOrderMode(OrderModeEnum.REQUISITION.getCode());
        order.setOrderType(OrderTypeEnum.REQUISITION_TO_PURCHASE.getCode());
        order.setDigest(orderVO.getDigest());

        //检查商品信息，获得订单总金额
        Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkSrmOrderProduct(order, orderVO.getProducts(), false);
        if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }

        // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
        if(productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
        }

        order.setProductAmount(productCheckResult.getData().getProductAmount());
        order.setFreight(BigDecimal.ZERO);
        order.setPromotionAmount(BigDecimal.ZERO);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));

        //发票信息
        Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getHasInvoice(), orderVO.getInvoice(), false);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //收货人信息
        Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), false);
        if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
        }

        // 其他要求
        Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
        if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
        }

        //支付记录，发货记录
        order.setPayments(new HashSet<>());
        order.setDeliveries(new HashSet<>());

        // 保存订单
        orderRepository.save(order);

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.MODIFY, order.getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.MODIFY, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");
        return Wrapper.success();
    }

    /**
     * 销售订单 - 转单
     *
     * @param headers         Http头部信息
     * @param transferOrderVO 接口参数
     * @return 转单结果
     */
    @Override
    public Wrapper<Void> transferOrders(HttpHeaders headers, VendorTransferOrderVO transferOrderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(transferOrderVO.getOrderIds());
        if(CollectionUtils.isEmpty(orders) || orders.stream().anyMatch(order -> !order.getVendorMemberId().equals(loginUser.getMemberId()) || !order.getVendorRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 判断角色Id
        if(transferOrderVO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_TRANSFER_NEED_ANOTHER_CONSUMER_ROLE);
        }

        //Step 2:判断转单条件
        if(orders.stream().anyMatch(order -> !baseOrderService.canTransferOrder(order))) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_TRANSFER);
        }

        //Step 3: 查询转单前订单的供应商，有没有设置发票信息
        Wrapper<Map<Long, OrderInvoiceDTO>> invoiceResult = baseOrderInvoiceService.findSupplyOrderInvoice(orders);
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        //Step 4: 查询上游供应商商品
        List<OrderProductDO> separateOrderProducts = baseOrderProductService.findByOrderIn(orders);
        if(CollectionUtils.isEmpty(separateOrderProducts)) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        Wrapper<List<SupplyProductDTO>> supplyProductResult = baseOrderProductService.findSupplyProducts(transferOrderVO.getRoleId(), orders, separateOrderProducts);
        if(supplyProductResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(supplyProductResult.getCode(), supplyProductResult.getMessage());
        }

        //Step 5: 物流服务：生成供应商收货人信息，计算转单订单的运费
        Wrapper<List<OrderConsigneeDTO>> logisticsResult = baseOrderConsigneeService.findVendorConsignees(orders, separateOrderProducts, supplyProductResult.getData());
        if(logisticsResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(logisticsResult.getCode(), logisticsResult.getMessage());
        }

        //Step 6: 查询上游供应商交易流程规则配置
        List<OrderShopProductBO> shopProducts = orders.stream().map(order ->
                new OrderShopProductBO(order, separateOrderProducts.stream().filter(orderProduct -> orderProduct.getOrder().getId().equals(order.getId())).collect(Collectors.toList()), supplyProductResult.getData())
        ).collect(Collectors.toList());
        Wrapper<Map<Long, OrderTradeProcessBO>> processResult = baseOrderProcessService.findVendorTradeProcess(shopProducts);
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //Step 7: 查询上游供应商支付方式与支付渠道配置
        Wrapper<Map<VendorBO, List<OrderPayTypeDetailVO>>> payTypeResult = baseOrderProcessService.checkMemberPayments(orders.stream().map(order -> new VendorBO(order.getSupplyMemberId(), order.getSupplyRoleId())).collect(Collectors.toList()));
        if(payTypeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(payTypeResult.getCode(), payTypeResult.getMessage());
        }

        //Step 8: 查询上游供应商业务员用户Id
        List<VendorBO> vendors = orders.stream().map(order -> new VendorBO(order.getSupplyMemberId(), order.getSupplyRoleId())).collect(Collectors.toList());
        Wrapper<List<OrderSalesDTO>> salesResult = baseOrderAuthService.findVendorSales(loginUser.getMemberId(), loginUser.getMemberRoleId(), vendors);
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        //Step 9: 查询上游供应商Logo
        List<VendorLogoDTO> supplyLogos = baseOrderService.batchFindVendorShopLogos(orders.stream().collect(Collectors.groupingBy(OrderDO::getShopId)).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream().map(ord -> new VendorBO(ord.getSupplyMemberId(), ord.getSupplyRoleId())).distinct().collect(Collectors.toList()))));

        //Step 10: 循环转单（销售订单生成采购订单）
        List<OrderDO> transferOrders = new ArrayList<>();
        for (OrderDO separateOrder : orders) {
            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setDeliverPeriod(StringUtils.hasLength(separateOrder.getDeliverPeriod()) ? separateOrder.getDeliverPeriod() : "");
            order.setBuyerMemberId(separateOrder.getVendorMemberId());
            order.setBuyerRoleId(transferOrderVO.getRoleId());
            order.setBuyerUserId(loginUser.getUserId());
            order.setBuyerMemberName(separateOrder.getVendorMemberName());
            order.setVendorMemberId(separateOrder.getSupplyMemberId());
            order.setVendorRoleId(separateOrder.getSupplyRoleId());
            order.setVendorMemberName(separateOrder.getSupplyMemberName());
            order.setVendorLogo(supplyLogos.stream().filter(logo -> logo.getShopId().equals(separateOrder.getShopId()) && logo.getVendorMemberId().equals(separateOrder.getSupplyMemberId()) && logo.getVendorRoleId().equals(separateOrder.getSupplyRoleId())).findFirst().map(VendorLogoDTO::getLogo).orElse(""));
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setLogisticsNo("");
            order.setShopId(separateOrder.getShopId());
            order.setShopType(separateOrder.getShopType());
            order.setShopEnvironment(separateOrder.getShopEnvironment());
            order.setShopName(separateOrder.getShopName());
            order.setOrderMode(separateOrder.getOrderMode());
            order.setOrderType(separateOrder.getOrderType());
            order.setOrderKind(separateOrder.getOrderKind());
            //转单后的询价报价单为空
            order.setQuoteId(0L);
            order.setQuoteNo("");
            order.setDigest(separateOrder.getDigest());
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //转单后没有了上级供应商
            order.setSupplyMemberId(0L);
            order.setSupplyRoleId(0L);
            order.setSupplyMemberName("");
            //设置转单后的拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.TRANSFERRED.getCode());
            order.setRelationId(separateOrder.getId());
            order.setRelationNo(separateOrder.getOrderNo());
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);
            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //设置原订单的关联Id
            separateOrder.setSeparateType(OrderSeparateTypeEnum.SEPARATED.getCode());
            separateOrder.setRelationId(order.getId());
            separateOrder.setRelationNo(order.getOrderNo());

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.transferOrderProduct(order, separateOrderProducts.stream().filter(product -> product.getOrder().getId().equals(separateOrder.getId())).collect(Collectors.toList()), supplyProductResult.getData());
            if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            //运费
            order.setFreight(logisticsResult.getData().stream().filter(orderConsignee -> orderConsignee.getOrderId().equals(separateOrder.getId())).map(orderConsignee -> orderConsignee.getFreight().setScale(2, RoundingMode.HALF_UP)).findFirst().orElse(BigDecimal.ZERO));
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setCouponAmount(BigDecimal.ZERO);
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);

            //工作流任务
            OrderTradeProcessBO tradeProcess = processResult.getData().getOrDefault(separateOrder.getId(), null);
            if(tradeProcess == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_SUPPLY_MEMBER_DOES_NOT_CONFIG_TRADE_PROCESS);
            }

            order.setTask(new OrderProcessTaskDO(tradeProcess, OrderProcessTypeEnum.TRADE.getCode()));

            //启动审核工作流
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.startOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            //更新供应商用户Id
            baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

            // 支付记录
            List<OrderPayTypeDetailVO> payTypeDetails = payTypeResult.getData().getOrDefault(new VendorBO(separateOrder.getSupplyMemberId(), separateOrder.getSupplyRoleId()), null);
            if(CollectionUtils.isEmpty(payTypeDetails)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_SUPPLY_MEMBER_HAS_NOT_PAYMENT_SETTING);
            }

            Wrapper<Void> paymentResult = baseOrderPaymentService.transferOrderPayments(order, tradeProcess.getPayNodes(), payTypeDetails);
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //合同信息
            Wrapper<Void> contractResult = baseOrderContractService.transferOrderContract(order, tradeProcess.getContractId());
            if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
            }

            //发票信息
            OrderInvoiceDTO orderInvoice = invoiceResult.getData().getOrDefault(separateOrder.getId(), null);
            if(Objects.nonNull(separateOrder.getInvoice()) && orderInvoice == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_VENDOR_MEMBER_INVOICE_DOES_NOT_EXIST);
            }

            Wrapper<Void> orderInvoiceResult = baseOrderInvoiceService.transferOrderInvoice(order, orderInvoice);
            if(orderInvoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(orderInvoiceResult.getCode(), orderInvoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.transferOrderConsignee(order, logisticsResult.getData().stream().filter(consigneeDTO -> consigneeDTO.getOrderId().equals(separateOrder.getId())).findFirst().orElse(null));
            if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.transferOrderRequirement(order, separateOrder);
            if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            transferOrders.add(order);
        }

        //保存
        orderRepository.saveAll(orders);
        orderRepository.saveAll(transferOrders);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(transferOrders);

        //Last Step : 订单创建完成后:
        transferOrders.forEach(order -> {
            //内部流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        return Wrapper.success();
    }

    /**
     * App - 订单创建之前，查询支付方式和支付渠道信息
     *
     * @param headers    HttpHeader信息
     * @param separateVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileProcessDetailVO> findMobileProcessPaymentSetting(HttpHeaders headers, OrderSeparateVO separateVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromMobile(headers);

        //同一个供应商相同skuId不能下单
        for (OrderSeparateVendorVO separateVendor : separateVO.getVendors()) {
            if (separateVendor.getProducts().size() != separateVendor.getProducts().stream().map(OrderSeparateProductVO::getSkuId).collect(Collectors.toSet()).size()) {
                return Wrapper.fail(ResponseCode.ORDER_PRODUCT_SKU_IS_CHECK_SAME);
            }
        }

        Wrapper<OrderProcessDetailVO> processResult = findOrderProcessPaymentSetting(loginUser.getMemberId(), loginUser.getMemberRoleId(), separateVO);
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //App或小程序，不能使用建行B2B支付，但可以使用数字人民币支付
        processResult.getData().getPayTypes().stream().filter(payType -> payType.getPayType().equals(OrderPayTypeEnum.CCB_PAY.getCode())).findFirst().ifPresent(payType -> payType.getPayChannels().removeIf(payChannel -> payChannel.getPayChannel().equals(OrderPayChannelEnum.CCB_B2B.getCode())));
        return Wrapper.success(new MobileProcessDetailVO(processResult.getData()));
    }

    /**
     * App - 创建B2B订单
     *
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Override
    public Wrapper<OrderCompleteVO> createMobileBusinessOrder(HttpHeaders headers, MobileBusinessOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        //规则校验：
        // a. 会员不能购买自己的商品
        if(loginUser.getMemberId().equals(orderVO.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        // b. 拆单规则
        Map<OrderSeparateDTO, List<BusinessOrderProductVO>> vendorMap = baseOrderService.separateBusinessOrder(orderVO.getVendorMemberId(), orderVO.getVendorRoleId(), orderVO.getVendorMemberName(), orderVO.getProducts());

        // c. 拆单运费
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(orderVO.getFreight(), orderVO.getConsignee(), vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> NumberUtil.notNullAndPositive(p.getLogisticsTemplateId()) && NumberUtil.notNullAndPositive(p.getWeight()) && NumberUtil.notNullAndPositive(p.getQuantity())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // e.根据拆单后的分组，校验供应商的交易流程规则配置
        Map<OrderSeparateDTO, OrderTradeProcessBO> vendorTradeProcessMap = new HashMap<>();
        for (Map.Entry<OrderSeparateDTO, List<BusinessOrderProductVO>> entry : vendorMap.entrySet()) {
            Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(entry.getKey().getVendorMemberId(), entry.getKey().getVendorRoleId(), orderVO.getShopId(), OrderTradeProcessTypeEnum.ORDER_TRADE, entry.getValue().stream().map(product -> new OrderProductBO(product.getProductId(), product.getSkuId())).collect(Collectors.toList()));
            if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(processResult.getCode(), processResult.getMessage());
            }

            vendorTradeProcessMap.put(entry.getKey(), processResult.getData());
        }

        // f.从交易服务中，校验询价商品的价格
        Wrapper<Void> priceCheckResult = baseOrderProductService.checkBusinessOrderProductPrices(orderVO.getQuoteNo(), orderVO.getProducts());
        if(priceCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(priceCheckResult.getCode(), priceCheckResult.getMessage());
        }

        // g. 查询供应商业务员用户Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(loginUser.getMemberId(), loginUser.getMemberRoleId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId());
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // h. 从店铺模板服务中，查询供应商的Logo
        Wrapper<VendorLogoDTO> logoResult = baseOrderService.checkVendorShopLogo(orderVO.getShopId(), orderVO.getVendorMemberId(), orderVO.getVendorRoleId());
        if(logoResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(logoResult.getCode(), logoResult.getMessage());
        }

        //是否需要支付、支付金额、支付次数
        boolean requirePayment = false;
        BigDecimal payAmount = BigDecimal.ZERO;
        Integer fundMode = 0;
        Integer batchNo = 0;

        //拆单
        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<BusinessOrderProductVO>> entry : vendorMap.entrySet()) {
            //获取该供应商的订单送货时间、订单备注
            AtomicReference<String> deliverPeriod = new AtomicReference<>("");
            AtomicReference<String> remark = new AtomicReference<>("");
            if(!CollectionUtils.isEmpty(orderVO.getDeliverTimes())) {
                orderVO.getDeliverTimes().stream().filter(deliverTime -> deliverTime.getVendorMemberId().equals(entry.getKey().getVendorMemberId()) && deliverTime.getVendorRoleId().equals(entry.getKey().getVendorRoleId())).findFirst().ifPresent(deliverTimeVO -> {
                    deliverPeriod.set(StringUtils.hasLength(deliverTimeVO.getDeliverTime()) ? deliverTimeVO.getDeliverTime() : "");
                    remark.set(StringUtils.hasLength(deliverTimeVO.getRemark()) ? deliverTimeVO.getRemark() : "");
                });
            }

            //交易流程
            OrderTradeProcessBO tradeProcess = vendorTradeProcessMap.getOrDefault(entry.getKey(), null);
            if(tradeProcess == null) {
                return Wrapper.fail(ResponseCode.ORDER_VENDOR_DOES_NOT_CONFIG_TRADE_PROCESS);
            }

            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setDeliverPeriod(deliverPeriod.get());
            order.setBuyerMemberId(loginUser.getMemberId());
            order.setBuyerRoleId(loginUser.getMemberRoleId());
            order.setBuyerUserId(loginUser.getUserId());
            order.setBuyerMemberName(loginUser.getCompany());
            order.setVendorMemberId(orderVO.getVendorMemberId());
            order.setVendorRoleId(orderVO.getVendorRoleId());
            order.setVendorMemberName(orderVO.getVendorMemberName());
            order.setVendorLogo(logoResult.getData().getLogo());
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setLogisticsNo("");
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            //B2B下单模式为“进货单下单”，订单类型为“现货采购”
            order.setOrderMode(OrderModeEnum.QUOTATION.getCode());
            order.setOrderType(OrderTypeEnum.SPOT_PURCHASING.getCode());
            order.setOrderKind(OrderSourceKindEnum.B2B.getCode());
            order.setQuoteId(orderVO.getQuoteId());
            order.setQuoteNo(orderVO.getQuoteNo());
            order.setDigest(StringUtils.hasText(orderVO.getDigest()) ? orderVO.getDigest().trim() : entry.getValue().stream().filter(product -> StringUtils.hasLength(product.getName())).map(BusinessOrderProductVO::getName).findFirst().orElse(""));
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //拆单、转单
            order.setSupplyMemberId(entry.getKey().getSupplyMemberId());
            order.setSupplyRoleId(entry.getKey().getSupplyRoleId());
            order.setSupplyMemberName(entry.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);
            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkBusinessOrderProduct(order, entry.getValue(), true);
            if(productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(entry.getKey(), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setCouponAmount(BigDecimal.ZERO);
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);

            //工作流任务
            order.setTask(new OrderProcessTaskDO(tradeProcess, OrderProcessTypeEnum.TRADE.getCode()));

            //执行审核工作流，App的B2B订单要跳过第一个流程步骤
            Wrapper<ProcessTaskBO> taskResult = tradeProcess.getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<OrderPaymentCheckBO> paymentResult = baseOrderPaymentService.checkOrderPayment(order, orderVO.getPayType(), orderVO.getPayChannel(), tradeProcess.getPayNodes());
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //判断、执行支付任务
            Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
            if(payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
            }

            //由于合并下单时，交易流程、支付次数和支付比例设置必须是一样的，所以“是否支付”，“支付次数”也是相同的
            requirePayment = taskResult.getData().getNextPay();
            fundMode = paymentResult.getData().getFundMode();
            batchNo = payTaskResult.getData().getBatchNo();
            payAmount = payAmount.add(payTaskResult.getData().getPayAmount());

            //合同信息
            Wrapper<Void> contractResult = baseOrderContractService.checkOrderContract(order, orderVO.getContract(), true);
            if(contractResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(contractResult.getCode(), contractResult.getMessage());
            }

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
            if(consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            // 其他要求
            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRemark(order, remark.get(), true);
            if(requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            //更新供应会员用户Id
            baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

            orders.add(order);
        }

        // 保存订单
        orderRepository.saveAll(orders);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(orders);

        //Last Step : 订单创建完成后:
        orders.forEach(order -> {
            //内部流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CREATE, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CREATE, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            // 通知报表服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        return Wrapper.success(new OrderCompleteVO(orders.stream().map(OrderDO::getId).collect(Collectors.toList()), requirePayment, fundMode, batchNo, orderVO.getPayType(), orderVO.getPayChannel(), payAmount));
    }

    /**
     * 代客下单 - 创建订单
     * @param headers HttpHeader信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> createAgentOrder(HttpHeaders headers, AgentOrderVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        //Step 1: 规则校验
        //a.校验供应商的交易流程规则配置
        Map<VendorBO, List<OrderProductVO>> vendorProductMap = orderVO.getProducts().stream().collect(Collectors.groupingBy(product -> new VendorBO(product.getVendorMemberId(), product.getVendorRoleId())));
        List<VendorProductBO> vendorProducts = vendorProductMap.entrySet().stream().map(entry -> {
            VendorProductBO vendorProduct = new VendorProductBO();
            vendorProduct.setVendorMemberId(entry.getKey().getVendorMemberId());
            vendorProduct.setVendorRoleId(entry.getKey().getVendorRoleId());
            vendorProduct.setProducts(entry.getValue().stream().map(p -> new OrderProductBO(p.getProductId(), p.getSkuId())).collect(Collectors.toList()));
            return vendorProduct;
        }).collect(Collectors.toList());

        //跨境电商商品流程和普通订单流程判断
        List<Boolean> crossBorders = orderVO.getProducts().stream().map(product -> !Objects.isNull(product.getCrossBorder()) && product.getCrossBorder()).distinct().collect(Collectors.toList());
        if(crossBorders.size() > 1) {
            return Wrapper.fail(ResponseCode.ORDER_PRODUCT_TRADE_PROCESS_IS_DIFFERENT);
        }

        Wrapper<OrderTradeProcessBO> processResult = baseOrderProcessService.findVendorTradeProcess(orderVO.getShopId(), crossBorders.get(0) ? OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT : OrderTradeProcessTypeEnum.ORDER_TRADE, vendorProducts);
        if (processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        // b.校验供应商商品的价格
        Wrapper<BigDecimal> priceCheckResult = baseOrderProductService.checkOrderProductPrices(orderVO.getBuyerMemberId(), orderVO.getBuyerRoleId(), loginUser.getMemberType(), orderVO.getShopId(), orderVO.getFreight(), vendorProductMap);
        if (priceCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(priceCheckResult.getCode(), priceCheckResult.getMessage());
        }

        // e. 查询供应商业务员用户Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(orderVO.getBuyerMemberId(), orderVO.getBuyerRoleId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        // c. 查询供应商Logo
        List<VendorLogoDTO> vendorLogos = baseOrderService.findVendorShopLogos(orderVO.getShopId(), orderVO.getProducts().stream().map(p -> new VendorBO(p.getVendorMemberId(), p.getVendorRoleId())).distinct().collect(Collectors.toList()));

        // c. 拆单条件
        // c-1: 按照供应商将订单商品分组
        Map<OrderSeparateDTO, List<OrderProductVO>> vendorMap = baseOrderService.separateBuyerOrder(orderVO.getProducts());

        // c-2: 查询分组之后的运费
        Map<OrderSeparateDTO, BigDecimal> freightMap = baseOrderProductService.findSeparateOrderFreight(priceCheckResult.getData(), orderVO.getConsignee(), vendorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, product -> product.getValue().stream().filter(p -> NumberUtil.notNullAndPositive(p.getLogisticsTemplateId()) && NumberUtil.notNullAndPositive(p.getWeight()) && NumberUtil.notNullAndPositive(p.getQuantity())).map(p -> p.getWeight().multiply(p.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add))));

        // c-3: 订单模式和订单类型
        OrderTypeModeBO orderTypeMode = baseOrderService.findOrderTypeMode(orderVO.getShopType());

        //生成的订单列表
        List<OrderDO> orders = new ArrayList<>();
        for (Map.Entry<OrderSeparateDTO, List<OrderProductVO>> vendor : vendorMap.entrySet()) {
            //创建订单
            OrderDO order = new OrderDO();
            order.setCreateTime(LocalDateTime.now());
            order.setSubmitTime(LocalDateTime.now());
            order.setDeliverPeriod(orderVO.getDeliverPeriod());
            order.setBuyerMemberId(orderVO.getBuyerMemberId());
            order.setBuyerRoleId(orderVO.getBuyerRoleId());
            //代客下单订单是“待分配”订单，所以不能设置采购商的用户Id
            order.setBuyerUserId(null);
            order.setBuyerMemberName(orderVO.getBuyerMemberName());
            order.setVendorMemberId(loginUser.getMemberId());
            order.setVendorRoleId(loginUser.getMemberRoleId());
            order.setVendorMemberName(loginUser.getCompany());
            order.setVendorLogo(vendorLogos.stream().filter(logo -> logo.getVendorMemberId().equals(vendor.getKey().getVendorMemberId()) && logo.getVendorRoleId().equals(vendor.getKey().getVendorRoleId())).findFirst().map(VendorLogoDTO::getLogo).orElse(""));
            order.setOrderNo(OrderStringUtil.randomUniqueNumber());
            order.setShopId(orderVO.getShopId());
            order.setShopType(orderVO.getShopType());
            order.setShopEnvironment(orderVO.getShopEnvironment());
            order.setShopName(orderVO.getShopName());
            order.setOrderMode(orderTypeMode.getOrderMode());
            order.setOrderType(orderTypeMode.getOrderType());

            order.setOrderKind(OrderSourceKindEnum.AGENT.getCode());
            order.setQuoteId(NumberUtil.isNullOrNegative(orderVO.getQuoteId()) ? 0L : orderVO.getQuoteId());
            order.setQuoteNo(StringUtils.hasLength(orderVO.getQuoteNo()) ? orderVO.getQuoteNo().trim() : "");
            order.setLogisticsNo("");
            order.setDigest(StringUtils.hasText(orderVO.getDigest()) ? orderVO.getDigest().trim() : vendor.getValue().stream().map(OrderProductVO::getName).filter(StringUtils::hasLength).findFirst().orElse(""));
            order.setCanRefund(false);
            order.setHasRefund(false);
            order.setHasPaid(false);
            order.setHasDelivered(false);
            order.setHasReceived(false);
            order.setBuyerCommented(false);
            order.setVendorCommented(false);
            //设置拆单、转单，避免代码Null值
            order.setSupplyMemberId(vendor.getKey().getSupplyMemberId());
            order.setSupplyRoleId(vendor.getKey().getSupplyRoleId());
            order.setSupplyMemberName(vendor.getKey().getSupplyMemberName());
            //在转单的时候再改变拆单类型，生成关联的订单Id
            order.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
            order.setRelationId(0L);
            order.setRelationNo("");
            //营销活动状态
            order.setPromotionStatus(OrderPromotionStatusEnum.NONE.getCode());
            order.setGroupId(0L);

            // 保存订单，以生成订单的Id
            orderRepository.saveAndFlush(order);

            //检查商品信息，获得订单总金额
            Wrapper<OrderProductCheckBO> productCheckResult = baseOrderProductService.checkBuyerOrderProduct(order, vendor.getValue(), true);
            if (productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
            }

            // 如果订单商品包含了“物流”配送方式，订单接收人信息不能为空
            if (productCheckResult.getData().getNeedConsignee() && orderVO.getConsignee() == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(ResponseCode.ORDER_CONSIGNEE_MUST_NOT_EMPTY);
            }

            order.setProductAmount(productCheckResult.getData().getProductAmount());
            order.setFreight(freightMap.getOrDefault(vendor.getKey(), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setCouponAmount(BigDecimal.ZERO);
            order.setTotalAmount(order.getProductAmount().add(order.getFreight()).subtract(order.getPromotionAmount()).subtract(order.getCouponAmount()).setScale(2, RoundingMode.HALF_UP));
            order.setPaidAmount(BigDecimal.ZERO);

            //工作流任务
            order.setTask(new OrderProcessTaskDO(processResult.getData(), OrderProcessTypeEnum.TRADE.getCode()));

            //执行审核工作流
            Wrapper<ProcessTaskBO> taskResult = processResult.getData().getSkipFirstStep() ? baseOrderTaskService.startOrderProcessThenExecFirstTask(order) : baseOrderTaskService.startOrderProcess(order);
            if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 支付记录
            Wrapper<Void> paymentResult = baseOrderPaymentService.checkOrderCreatePayment(order, processResult.getData().getPayNodes(), orderVO.getPayments(), true);
            if(paymentResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(paymentResult.getCode(), paymentResult.getMessage());
            }

            //判断、执行支付任务
            Wrapper<OrderPaymentBO> payTaskResult = baseOrderPaymentService.startOrderPaySerialTasks(order);
            if (payTaskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(payTaskResult.getCode(), payTaskResult.getMessage());
            }

            //发票信息
            Wrapper<Void> invoiceResult = baseOrderInvoiceService.checkOrderInvoice(order, orderVO.getInvoice(), true);
            if (invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
            }

            //收货人信息
            Wrapper<Void> consigneeResult = baseOrderConsigneeService.checkOrderConsignee(order, orderVO.getConsignee(), true);
            if (consigneeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(consigneeResult.getCode(), consigneeResult.getMessage());
            }

            // 其他要求
            Wrapper<Void> requirementResult = baseOrderRequirementService.checkOrderRequirement(order, orderVO.getRequirement(), true);
            if (requirementResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(requirementResult.getCode(), requirementResult.getMessage());
            }

            //扣减库存
            Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
            if (deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
            }

            //发货记录
            order.setDeliveries(new HashSet<>());

            //更新供应会员用户Id
            baseOrderAuthService.updateVendorUserId(order, salesResult.getData());

            orders.add(order);
        }

        // 批量保存订单
        orderRepository.saveAll(orders);

        //供应商交易流程规则配置中的自动取消
        baseOrderScheduleService.scheduleOrderCancel(orders);

        List<OrderIdBO> orderIds = orders.stream().map(order -> new OrderIdBO(order.getId(), order.getOrderNo())).collect(Collectors.toList());

        //内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), orderIds, OrderOperationEnum.CREATE, orders.get(0).getBuyerInnerStatus(), "");
        baseOrderHistoryService.saveBuyerOrderOuterHistory(orderIds, loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getCompany(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, orders.get(0).getOuterStatus(), OrderOuterStatusEnum.getNameByCode(orders.get(0).getOuterStatus()), "");

        orders.forEach(order -> {
            // 通知报表服务，统计供应商的订单金额
            baseOrderService.reportVendorOrderAmount(order);
            // 通知报表服务，统计采购商、供应商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), null, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());
            // 通知消息服务，发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());
        });

        return Wrapper.success();
    }

    /**
     * “进货单”-待结算订单-查询积分列表
     * @param headers HttpHeader信息
     * @param lrcVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<OrderLrcDetailVO>> getLrcList(HttpHeaders headers, OrderLrcVO lrcVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderLrcDetailVO> respList = orderParamConfigService.getOrderScoreAndDeductionConfigList(loginUser.getMemberId(), loginUser.getMemberRoleId(), lrcVO);
        if(CollectionUtil.isEmpty(respList)){
            respList=Collections.emptyList();
        }
        return Wrapper.success(respList);
    }

    /**
     * 交换身份
     * @param saveVO
     * @param loginUser
     * @return
     */
    private UserLoginCacheDTO buildAgentUser(OrderLrcVO saveVO,UserLoginCacheDTO loginUser) {
        OrderLrcItemVO item = saveVO.getItemList().get(0);
        //校验供采关系
        MemberFeignVO feignVO=new MemberFeignVO();
        feignVO.setMemberId(loginUser.getMemberId());
        feignVO.setRoleId(loginUser.getMemberRoleId());
        Wrapper<List<MemberFeignQueryVO>> listWrapper = memberInnerControllerFeign.listAllLowerMembers(feignVO);
        if(listWrapper.getCode()!=ResponseCode.SUCCESS.getCode()||CollectionUtil.isEmpty(listWrapper.getData())){
            throw new BusinessException(ResponseCode.PARAM_NOT_EXIST);
        }
        List<MemberFeignQueryVO> collect = listWrapper.getData().stream().filter(o -> o.getMemberId().equals(item.getVendorMemberId())&&o.getRoleId().equals(item.getVendorRoleId())).collect(Collectors.toList());
        if(CollectionUtil.isEmpty(collect)) {
            throw new BusinessException(ResponseCode.PARAM_NOT_EXIST);
        }
        // 创建
        UserLoginCacheDTO agentUser = new UserLoginCacheDTO();
        agentUser.setMemberId(item.getVendorMemberId());
        agentUser.setMemberRoleId(item.getVendorRoleId());
        item.setVendorMemberId(loginUser.getMemberId());
        item.setVendorRoleId(loginUser.getMemberRoleId());

        return agentUser;
    }
    
    @Override
    public Wrapper<List<OrderLrcDetailVO>> getLrcListByAgent(HttpHeaders headers, OrderLrcVO lrcVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        loginUser = buildAgentUser(lrcVO,loginUser);
        List<OrderLrcDetailVO> respList = orderParamConfigService.getOrderScoreAndDeductionConfigList(loginUser.getMemberId(), loginUser.getMemberRoleId(), lrcVO);
        if(CollectionUtil.isEmpty(respList)){
            respList=Collections.emptyList();
        }
        return Wrapper.success(respList);
    }
}
